/*
 * Translated from the Koprina project, a Java implementation of the Skype SILK codec
 * http://code.google.com/p/koprina/
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SilkSharp
{
	/*
	 * First-order allpass filter with 
	 * transfer function:
	 * 
	 *         A + Z^(-1) 
	 * H(z) = ------------ 
	 *        1 + A*Z^(-1) 
	 *
	 * Implemented using minimum multiplier filter design. 
	 *  
	 * Reference: http://www.univ.trieste.it/~ramponi/teaching/
	 * DSP/materiale/Ch6(2).pdf
	 * 
	 * @author Dingxin Xu
	 */
	public class Silk_allpass_int
	{
		/*
		 * First-order allpass filter.
		 * @param in Q25 input signal [len]
		 * @param in_offset offset of valid data.
		 * @param S Q25 state [1]
		 * @param S_offset offset of valid data.
		 * @param A Q15 coefficient    (0 <= A < 32768)
		 * @param out Q25 output signal [len]
		 * @param out_offset offset of valid data.
		 * @param len Number of samples
		 */
		public static void SKP_Silk_allpass_int(
			int[] _in,    /* I:    Q25 input signal [len]               */
			int in_offset,
			int[] S,     /* I/O:  Q25 state [1]                         */
			int S_offset,
			int A,      /* I:    Q15 coefficient    (0 <= A < 32768)  */
			int[] _out,   /* O:    Q25 output signal [len]              */
			int out_offset,
			int len     /* I:    Number of samples                    */
		)
		{
			int Y2, X2, S0;
			int k;

			S0 = S[ S_offset + 0 ];
			for( k = len - 1; k >= 0; k-- )
			{
				Y2 = _in[ in_offset + 0 ] - S0;
				X2 = ( Y2 >> 15 ) * A + ( ( ( Y2 & 0x00007FFF ) * A ) >> 15 );
				( _out[ out_offset++ ] ) = S0 + X2;
				S0 = _in[ in_offset++ ] + X2;
			}
			S[ S_offset + 0 ] = S0;
		}
	}
}
